package edu.purdue.cs.aggr.messageprocessor;

import edu.purdue.cs.aggr.AggrException;
import edu.purdue.cs.aggr.Controller;
import edu.purdue.cs.aggr.Node;
import edu.purdue.cs.aggr.VertexManager;
import edu.purdue.cs.aggr.message.AccumulatorMessage;
import edu.purdue.cs.aggr.message.ConnectionEstablishmentMessage;
import edu.purdue.cs.aggr.message.ControllerCommandMessage;
import edu.purdue.cs.aggr.message.EventNotificationMessage;
import edu.purdue.cs.aggr.message.Message;
import edu.purdue.cs.aggr.message.VertexMoveCommand;
import edu.purdue.cs.aggr.message.VertexSetupMessage;
import edu.purdue.cs.aggr.message.VertexTransferMessage;
import edu.purdue.cs.aggr.message.VertexUpdateMessage;

public class MessageProcessorFactory {
	
	public static MessageProcessor getMessageProcessor (Node node, Message message) throws AggrException {
		if (message instanceof VertexSetupMessage) {
			if(! (node instanceof VertexManager)) {
				throw new AggrException("A VertexSetupMessage was delivered to a non-vertex node");
			}
			return new VertexSetupMessageProcessor((VertexManager) node);
		} else if (message instanceof VertexUpdateMessage) {      
		  if(! (node instanceof VertexManager)) {
		    throw new AggrException("A VertexUpdateMessage was delivered to a non-vertex node");
		  }
		  return new VertexUpdateMessageProcessor((VertexManager) node);
    } else if (message instanceof AccumulatorMessage) {
			return new AccumulatorMessageProcessor((VertexManager) node);
		} else if (message instanceof EventNotificationMessage) {
			return new EventNotifiationMessageProcessor(node);
		} else if (message instanceof ConnectionEstablishmentMessage) {
			return new ConnectionEstablishmentMessageProcessor();
		} else if (message instanceof VertexTransferMessage) {
      return new VertexTransferMessageProcessor((VertexManager) node);
    } else if (message instanceof VertexMoveCommand) {
      return new VertexMoveCommandProcessor((VertexManager) node);
    } else if (message instanceof ControllerCommandMessage) {
      if(! (node instanceof Controller)) {
        throw new AggrException("A ControllerCommandMessage was delivered to a non-controller node");
      }
      return new ControllerCommandMessageProcessor((Controller) node);
    }
		throw new AggrException("No message processor defined for the passed message instance");
	}
	
}
